package testDataGenerator.model;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import testDataGenerator.model.exception.InvalidConfigurationFileException;
import testDataGenerator.model.exception.MultipleUniqueColumnException;

public class TestDataGenerator {
	private final List<DataSet> dataSets;
	private Worker worker;

	public TestDataGenerator(String fileName) throws DocumentException,
			InvalidConfigurationFileException {
		dataSets = new ArrayList<DataSet>();
		SAXReader reader = new SAXReader();
		Document document = reader.read(fileName);
		Element root = document.getRootElement();
		for (Iterator<Element> i = root.elementIterator(); i.hasNext();) {
			Element element = i.next();
			try {
				dataSets.add(new DataSet(element, new DataTypeFactory(),
						new GenerationMethodFactory()));
			} catch (MultipleUniqueColumnException e) {
				throw new InvalidConfigurationFileException();
			}
		}
	}

	public List<DataSet> getDataSets() {
		return this.dataSets;
	}

	public void start() {
		worker = new Worker(this);
		new Thread(worker).start();
		System.out.println("Start generating test data...");
	}

	public double getProgress() {
		if (worker != null)
			return worker.getProgress();
		else
			return 0;
	}

	class Worker implements Runnable {
		private final int totalDataCount;
		private TestDataGenerator generator;

		Worker(TestDataGenerator generator) {
			this.generator = generator;
			totalDataCount = getTotalDataCount();
		}

		private int getTotalDataCount() {
			int counter = 0;
			for (DataSet ds : generator.dataSets) {
				counter = counter + ds.getDataColumns().size()
						* ds.getNumberOfRows();
			}
			// System.out.println("total: "+counter);
			return counter;
		}

		private int getCurrentDataCount() {
			int counter = 0;
			for (DataSet ds : generator.dataSets) {
				List<DataColumn> columns = ds.getDataColumns();
				for (int i = 0; i < columns.size(); i++) {
					counter = counter + columns.get(i).getDataCount();
				}
			}
			// System.out.println("Generated: "+counter);
			return counter;
		}

		double getProgress() {
			return ((double) getCurrentDataCount()) / ((double) totalDataCount);
		}

		public void run() {
			for (DataSet dataSet : this.generator.dataSets) {
				List<DataColumn> columns = dataSet.getDataColumns();
				for (int i = 0; i < columns.size(); i++) {
					columns.get(i).generateData(dataSet.getNumberOfRows());
				}
			}

		}

	}

}
